/**
 * @param {String} div
 * @param {Number} lat
 * @param {Number} lng
 * @constructor
 */
function GoogleMap(div, lat, lng) {
    this.geocoder = new google.maps.Geocoder();
    this.map = new google.maps.Map(
        document.getElementById(div),
        {
            draggableCursor: 'crosshair',
            draggingCursor: 'crosshair',
            zoom: 16,
            mapTypeId: google.maps.MapTypeId.ROADMAP,
            scrollwheel: false
        }
    );
    /**
     * @type {google.maps.Marker}
     */
    this.begin = null;
    /**
     * @type {google.maps.Marker}
     */
    this.flag = null;
    this.directionsRenderer = new google.maps.DirectionsRenderer();
    this.directionsRenderer.setMap(this.map);
    this.directionsService = new google.maps.DirectionsService();

    if (lat && lng) {
        this.map.setCenter(new google.maps.LatLng(lat, lng));
    } else if (navigator.geolocation) {
        var map = this.map;
        navigator.geolocation.getCurrentPosition(function (pos) {
            map.setCenter(new google.maps.LatLng(
                pos.coords.latitude,
                pos.coords.longitude
            ));
        });
    }
}

/**
 * @param {String} address
 * @param {function(Array.<google.maps.GeocoderResult>, google.maps.GeocoderStatus)} callback
 * @return void
 */
GoogleMap.prototype.searchAddress = function (address, callback) {
    this.geocoder.geocode(
        {address: address},
        callback
    );
};

GoogleMap.prototype.addRightClickListener = function (handler) {
    google.maps.event.addListener(this.map, 'rightclick', handler);
};

/**
 * @param {Number} lat
 * @param {Number} lng
 * @return void
 */
GoogleMap.prototype.setCenter = function (lat, lng) {
    this.map.setCenter(new google.maps.LatLng(lat, lng));
};

/**
 * @param {Number} lat
 * @param {Number} lng
 * @return void
 */
GoogleMap.prototype.setBegin = function (lat, lng) {
    if (this.begin) {
        this.begin.setMap(null);
    }

    this.begin = new google.maps.Marker({
        position: new google.maps.LatLng(lat, lng),
        icon: 'http://maps.google.com/mapfiles/ms/micons/homegardenbusiness.png'
    });
    this.begin.setMap(this.map);

    if (this.begin && this.flag) {
        var request = {
            origin: this.begin.getPosition(),
            destination: this.flag.getPosition(),
            travelMode: google.maps.TravelMode.DRIVING
        };

        var directionsRenderer = this.directionsRenderer;
        var directionsService = this.directionsService;
        directionsService.route(request, function(response, status) {
            if (status == google.maps.DirectionsStatus.OK) {
                directionsRenderer.setDirections(response);
            }
        });
    }
};

/**
 * @return void
 */
GoogleMap.prototype.moveToBegin = function () {
    if (this.flag) {
        this.map.setCenter(this.begin.getPosition());
    }
};

/**
 * @param {Number} lat
 * @param {Number} lng
 * @return void
 */
GoogleMap.prototype.setFlag = function (lat, lng) {
    if (this.flag) {
        this.flag.setMap(null);
    }

    this.flag = new google.maps.Marker({
        position: new google.maps.LatLng(lat, lng),
        icon: 'https://maps.google.com/mapfiles/kml/shapes/schools_maps.png',
        shadow: 'https://maps.google.com/mapfiles/kml/shapes/schools_maps.shadow.png'
    });
    this.flag.setMap(this.map);
};

/**
 * @return void
 */
GoogleMap.prototype.moveToFlag = function () {
    if (this.flag) {
        this.map.setCenter(this.flag.getPosition());
    }
};
